package com.lx.constant.segment;

import cn.hutool.core.util.StrUtil;
import com.lx.common.utils.SqlClassUtil;
import com.lx.constant.consts.CommonConstant;
import com.lx.constant.enums.ConditionKeyWordEnum;
import com.lx.constant.enums.SegmentEnum;
import com.lx.inter.ReplaceComparator;
import com.lx.wrapper.AbstractWrapper;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.query.Query;

import javax.persistence.Column;
import javax.persistence.JoinColumn;
import java.lang.reflect.Field;

/**
 * 基础SQL语句构建对象
 *
 * @author lx
 * @create 2022/12/5 16:06
 **/
@Getter
@Setter
public class Segment implements ReplaceComparator<Segment> {

    /**
     * 语句类型
     */
    private SegmentEnum segmentType;

    /**
     * 列名是否需要使用驼峰命名法解析,仅当{isHQL}为false生效
     */
    private boolean openHump = true;

    /**
     * 列项对应实体类型
     */
    private Class<?> columnEntityClass;

    /**
     * 列项属性
     */
    private Field columnField;

    /**
     * 列项属性名称(如列项属性存在,则该字段一定存在)
     */
    private String columnFieldName;

    /**
     * 列名名称
     */
    private String columnName;

    /**
     * 根据Segment对象构建子语句
     *
     * @param parentWrapper
     * @param thisWrapper
     * @param isHQL
     * @return
     */
    public String convertSegmentToQL(AbstractWrapper parentWrapper, AbstractWrapper thisWrapper, boolean isHQL) {
        String columnName = getColumnNameBySegment(isHQL);
        return columnName == null ? null : thisWrapper.getTableAliasName(true, this.getColumnEntityClass()) + columnName;
    }

    /**
     * * 根据属性类获取符合期望排名的列名,期望排名如下:
     * * 1.获取用户手动输入的 {columnName}字符串
     * * 2.获取 {@link Column}的name.
     * * 3.获取 {@link JoinColumn}的name.
     * * 4.获取 属性名称,根据列定义判断是否使用驼峰命名法定义.
     *
     * @param isHQL
     * @return
     */
    public String getColumnNameBySegment(boolean isHQL) {
        String columnName = this.getColumnName();
        if (StrUtil.isNotEmpty(columnName)) {
            return columnName;
        }
        //根据相关注解或配置寻找列属性
        return SqlClassUtil.findColumnNameByField(isHQL, columnField, this.isOpenHump());
    }

    /**
     * 获取Hibernate占位符
     *
     * @param needAddColon 是否需要添加冒号标识符
     * @return
     */
    public String getHibernatePlaceholder(boolean needAddColon) {
        return new StringBuilder(32)
                .append(needAddColon ? CommonConstant.COLON : CommonConstant.EMPTY)
                .append(getColumnEntityClass() == null ? "entity" : getColumnEntityClass().getSimpleName())
                .append(getSegmentType().name())
                .append(getColumnFieldName() == null ? columnName : columnField.getName())
                .toString();
    }

    /**
     * 当前语句是否需要拼接连接字符
     *
     * @param joinSep
     * @param prevSegment 上一个语句节点
     * @return
     */
    public boolean needJoinSep(ConditionKeyWordEnum joinSep, Segment prevSegment) {
        return true;
    }

    /**
     * 当前Segment设置Query参数列表值
     *
     * @param isHQL
     * @param query
     */
    public void setHibernateParamByQuery(boolean isHQL, Query query) {
        return;
    }

    @Override
    public boolean needReplace(Segment t1) {
        return false;
    }
}
